<?php
/**
 * bll msg
 * @package app-file_lib_bll
 */
load_lib('/bll/file');
load_lib('/dao/filemsgdao');
/**
 * bll msg
 * @author pandajingjing
 * @package app-file_lib_bll
 */
class bll_msg extends bll_file{
	
	/**
	 * 处理过的消息数
	 * @var int
	 */
	private $_intMsgCnt=0;

	function __construct(){
		parent::__construct();
	}

	/**
	 * 处理DFS的消息队列
	 */
	function doDFSMsg(){
		dao_filemsgdao::consumeMessage(array( 
				$this,
				'processMsg' 
		));
		return $this->_intMsgCnt;
	}

	/**
	 * 队列消息处理逻辑
	 * @param mix $p_mixMsg
	 */
	function processMsg($p_mixMsg){
		$arrParam=$p_mixMsg->getBody();
		switch($arrParam['MSGTYPE']){
			case 1: //新增图片
				$this->saveFileInfo($arrParam);
				$this->backupFile($arrParam);
				break;
			case 2: //有存储出现损坏,需要矫正主存储和备份数据
				$this->backupFile($arrParam);
				break;
			case 3: //文件所有备份均损坏,删除所有数据
				$this->deleteFile($arrParam);
				break;
		}
		++$this->_intMsgCnt;
		$p_mixMsg->fade();
	}

	/**
	 * 保存文件信息
	 * @param array $p_arrParam
	 */
	function saveFileInfo($p_arrParam){
		$strFileKey=$p_arrParam['FILEKEY'];
		$arrFileInfo=array( 
				'FILEKEY'=>$strFileKey,
				'FILESIZE'=>$p_arrParam['FILESIZE'],
				'FILEEXT'=>$p_arrParam['FILEEXT'],
				'FROMDOMAIN'=>$p_arrParam['FROMDOMAIN'],
				'FROMIP'=>$p_arrParam['FROMIP'],
				'CREATETIME'=>$p_arrParam['CREATETIME'] 
		);
		dao_filemsgdao::saveFileInfo($arrFileInfo);
		if(isset($p_arrParam['WIDTH'])){
			$arrImageInfo=array( 
					'FILEKEY'=>$strFileKey,
					'WIDTH'=>$p_arrParam['WIDTH'],
					'HEIGHT'=>$p_arrParam['HEIGHT'],
					'CHANNELS'=>$p_arrParam['CHANNELS'],
					'BITS'=>$p_arrParam['BITS']
			);
			dao_filemsgdao::saveImageInfo($arrImageInfo);
		}
	}

	/**
	 * 备份文件
	 * @param array $p_arrParam
	 */
	function backupFile($p_arrParam){
		$strFileKey=$p_arrParam['FILEKEY'];
		$mixBackupInfo=dao_filemsgdao::getFileBackup($strFileKey);
		if(null===$mixBackupInfo){
			$arrBackedHostID=array( 
					$p_arrParam['HOSTID'] 
			);
			dao_filemsgdao::startBackup(array( 
					'FILEKEY'=>$strFileKey 
			));
		}else{
			$strBackedHostIDs=$mixBackupInfo['BACKHOSTID'];
			$arrBackedHostID=explode(',',$strBackedHostIDs);
			if(isset($p_arrParam['ERRHOSTIDS'])){
				$arrTmpIDs=array();
				foreach($arrBackedHostID as $intBackedHostID){
					if(in_array($intBackedHostID,$p_arrParam['ERRHOSTIDS'])){
						
					}else{
						$arrTmpIDs[]=$intBackedHostID;
					}
				}
				$arrBackedHostID=$arrTmpIDs;
			}
		}
		$intBackupCnt=dao_filemsgdao::getConfig('backup_cnt','backup');
		$intBackedCnt=count($arrBackedHostID);
		$intNeedBackupCnt=$intBackupCnt-$intBackedCnt;
		for($i=0;$i<$intNeedBackupCnt;++$i){
			$intBackupHostID=$this->dispatchBackupHostID($arrBackedHostID);
			if(null===$intBackupHostID){

			}else{
				$strSubDir=$this->dispatchFile($strFileKey);
				$strBaseDir=dao_filemsgdao::getConfig('raw','storage');
				$strDestDir=$strBaseDir.DIRECTORY_SEPARATOR.$intBackupHostID.$strSubDir;
				load_lib('/util/file');
				if(!is_dir($strDestDir)){
					if(false===util_file::tryMakeDir($strDestDir,0755,true)){
						throw new Exception(__CLASS__.': can not create path('.$strDestDir.').');
						return false;
					}
				}
				$strDestFile=$strDestDir.$strFileKey;
				$strSourceDir=$strBaseDir.DIRECTORY_SEPARATOR.$p_arrParam['HOSTID'].$strSubDir;
				$strSourceFile=$strSourceDir.$strFileKey;
				if(false===util_file::tryCopyFile($strSourceFile,$strDestFile,true)){
					throw new Exception(__CLASS__.': can not copy ('.$strDestFile.') from ('.$strSourceFile.').');
					return false;
				}
				$arrBackedHostID[]=$intBackupHostID;
				$arrBackupInfo=array( 
						'FILEKEY'=>$strFileKey,
						'BACKHOSTID'=>implode(',',$arrBackedHostID) 
				);
				dao_filemsgdao::saveBackupInfo($arrBackupInfo);
			}
		}
	}

	/**
	 * 所有备份全部损坏,清除文件数据,等待重新上传
	 * @param array $p_arrParam
	 */
	function deleteFile($p_arrParam){
		$arrDelInfo=array('FILEKEY'=>$p_arrParam['FILEKEY']);
		dao_filemsgdao::deleteFileInfo($arrDelInfo);
	}
	
	/**
	 * 获取分配备份存储设备
	 * @param array $p_arrExceptHostIDs
	 */
	function dispatchBackupHostID($p_arrExceptHostIDs){
		$arrBackupHostIDs=dao_filemsgdao::getConfig('storage_host_id','backup');
		for($i=0;$i<50;++$i){ //只循环50次,如果始终找不到hostid,要么是存储设备不够,要么备份存储设备太多
			$intHostID=$this->dispatchHostID($arrBackupHostIDs);
			if(in_array($intHostID,$p_arrExceptHostIDs)){
				continue;
			}
			return $intHostID;
		}
		return null;
	}
}